/********************************************************************************
 * Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH  *
 *                                                                              *
 *              This software is distributed under the terms of the             *
 *              GNU Lesser General Public Licence (LGPL) version 3,             *
 *                  copied verbatim in the file "LICENSE"                       *
 ********************************************************************************/
/**  FairMCPoint.h
 * This is the base class for all MC Points generated by the transport of
 * tracks through active detectors.
 **/

#ifndef FAIRMCPOINT_H
#define FAIRMCPOINT_H

#include "FairMultiLinkedData_Interface.h"   // for FairMultiLinkedData

#include <Rtypes.h>     // for Double_t, Double32_t, Int_t, etc
#include <TVector3.h>   // for TVector3

class FairMCPoint : public FairMultiLinkedData_Interface
{
  public:
    /** Default constructor **/
    FairMCPoint();

    /** Constructor with arguments
     *@param trackID  Index of MCTrack
     *@param detID    Detector ID
     *@param pos      Point coordinates [cm]
     *@param mom      Momentum of track at MCPoint [GeV]
     *@param tof      Time since event start [ns]
     *@param length   Track length since creation [cm]
     *@param eLoss    Energy deposit [GeV]
     *@param EventId  MC event id
     **/
    FairMCPoint(Int_t trackID,
                Int_t detID,
                TVector3 pos,
                TVector3 mom,
                Double_t tof,
                Double_t length,
                Double_t eLoss,
                UInt_t EventId = 0);

    /** Destructor **/
    ~FairMCPoint() override;

    /** Accessors */
    UInt_t GetEventID() const { return fEventId; }   /// event identifier
    Int_t GetTrackID() const { return fTrackID; }
    Double_t GetPx() const { return fPx; }
    Double_t GetPy() const { return fPy; }
    Double_t GetPz() const { return fPz; }
    Double_t GetTime() const { return fTime; }
    Double_t GetLength() const { return fLength; }
    Double_t GetEnergyLoss() const { return fELoss; }
    void Momentum(TVector3& mom) const { mom.SetXYZ(fPx, fPy, fPz); }
    Int_t GetDetectorID() const { return fDetectorID; };
    Double_t GetX() const { return fX; };
    Double_t GetY() const { return fY; };
    Double_t GetZ() const { return fZ; };
    void Position(TVector3& pos) const { pos.SetXYZ(fX, fY, fZ); }

    /** Modifiers **/
    void SetEventID(UInt_t eventId) { fEventId = eventId; }
    virtual void SetTrackID(Int_t id) { fTrackID = id; }
    void SetTime(Double_t time) { fTime = time; }
    void SetLength(Double_t length) { fLength = length; }
    void SetEnergyLoss(Double_t eLoss) { fELoss = eLoss; }
    void SetMomentum(const TVector3& mom);
    void SetDetectorID(Int_t detID) { fDetectorID = detID; }
    void SetX(Double_t x) { fX = x; }
    void SetY(Double_t y) { fY = y; }
    void SetZ(Double_t z) { fZ = z; }
    void SetXYZ(Double_t x, Double_t y, Double_t z);
    void SetPosition(const TVector3& pos);

    /** Output to screen **/
    void Print(const Option_t* opt = nullptr) const override;

  protected:
    Int_t fTrackID;             ///< Track index
    UInt_t fEventId;            ///< MC Event id
    Double32_t fPx, fPy, fPz;   ///< Momentum components [GeV]
    Double32_t fTime;           ///< Time since event start [ns]
    Double32_t fLength;         ///< Track length since creation [cm]
    Double32_t fELoss;          ///< Energy loss at this point [GeV]
    Int_t fDetectorID;          ///< Detector unique identifier
    Double32_t fX, fY, fZ;      ///< Position of hit [cm]

    ClassDefOverride(FairMCPoint, 5);
};

inline void FairMCPoint::SetMomentum(const TVector3& mom)
{
    fPx = mom.Px();
    fPy = mom.Py();
    fPz = mom.Pz();
}

inline void FairMCPoint::SetXYZ(Double_t x, Double_t y, Double_t z)
{
    fX = x;
    fY = y;
    fZ = z;
}

inline void FairMCPoint::SetPosition(const TVector3& pos)
{
    fX = pos.X();
    fY = pos.Y();
    fZ = pos.Z();
}

#endif   // FAIRMCPOINT_H
